#pragma once
#include<wrl/client.h>
#include<wrl/implements.h>
#include<mfapi.h>

using namespace Microsoft::WRL;

namespace GuitarFX_Audio
{
	template<class T>
	class CAsyncCallback : public RuntimeClass< RuntimeClassFlags< ClassicCom >, IMFAsyncCallback >
	{
		DWORD m_dwQueueId;
	public:
		typedef HRESULT(T::*InvokeFn)(IMFAsyncResult *pAsyncResult);

		CAsyncCallback(T ^pParent, InvokeFn fn) : m_pParent(pParent), m_pInvokeFn(fn), m_QueueId(0)
		{
		}

		// IMFAsyncCallback methods
		STDMETHODIMP GetParameters(DWORD *pdwFlags, DWORD *pdwQueue)
		{
			// This is the Media Foundation Work Queue id the async callback will be executed
			// Call SetQueueID with appropriate value to execute the callback on as MMCSS thread
			*pdwQueue = m_dwQueueId;
			*pdwFlags = 0;
			return S_OK;
		}

		STDMETHODIMP Invoke(IMFAsyncResult* pAsyncResult)
		{
			return (m_pParent->*m_pInvokeFn)(pAsyncResult);
		}

		void SetQueueID(DWORD dwQueueId)
		{
			m_dwQueueId = dwQueueId;
		}

		T ^m_pParent;
		InvokeFn m_pInvokeFn;
	};

// Helper to define both callback helper object and callback method
#define IMPLEMENT_MFASYNC_CALLBACK(class_name,callback_name) \
	CAsyncCallback<##class_name> m_##callback_name; \
	HRESULT On##callback_name(IMFAsyncResult *); 
	
}


